#' 多变量提取暴露数据
#'
#' @param exposure 必须是list, 例如list(df,'ieu-a-2')，df必须U1_Clean_data是清洗后的数据框，
#' 'ieu-a-2'是正常的ID，可以随意组合，都是ID和都是数据框也行
#' @param p 提取工具变量的P值
#' @param clump 在线或本地，在线为"online", 本地为"local"，默认在线
#' @param r2 默认是0.001， 0.01等也可使用
#' @param kb 默认是10000， 1000,500等也可使用
#' @param max_retries 是重试计算器，默认是10
#' @param pop 默认是欧洲"EUR"
#' @param bfile clump模板文件的位置，U1_set_file_path功能设置过路径后就不需要填了。
#' @param plink_bin plink软件的位置，U1_set_file_path功能设置过路径后就不需要填了。
#'
#' @return 多变量的暴露
#' @export
#'
#' @examples
#'
#' \dontrun{
#'
#' library(Oneclick)
#'
#' exposure<-  list(
#'   df,
#'   'ieu-a-2'
#' )
#'
#' mv_exposures <- M1_mv_extract_exposures(exposure)
#'
#' }
#'
#'
M1_mv_extract_exposures<- function(exposure,
                                               p = 5e-08,
                                               clump = "online",
                                               r2 = 0.001,
                                               kb = 10000,
                                               max_retries = 10,
                                               pop = "EUR",
                                               bfile= "",
                                               plink_bin = "")
{
  require(TwoSampleMR)
  stopifnot( class(exposure) %in% "list"  )

  # 缩小SNP范围，获得亚集的SNP

  SNP_all <- c()

  cli::cli_process_start("获得单个暴露的工具变量")

  l_inst <- list()
  for (i in 1:length(exposure)) {
    suppressMessages(
    exposure_IV<-U2_extract_instruments(exposure[[i]],
                                        p = p ,
                                        clump = clump,
                                        r2 = r2,
                                        kb = kb,
                                        max_retries = max_retries,
                                        pop = pop,
                                        bfile = bfile,
                                        plink_bin = plink_bin)
    )


    l_inst[[i]] <- exposure_IV
    # l_inst[[i]][["id.exposure"]]<-l_inst[[i]][["exposure"]]

    SNP_all <- plyr::rbind.fill(SNP_all, exposure_IV)

  }

  cli::cli_process_done()

  cli::cli_process_start("获得合并暴露工具变量的完整数据")

  l_full <- list()
  for ( i in 1:length(exposure) ) {
    suppressMessages(
    l_full[[i]]<-U3_extract_outcomes_data(outcome = exposure[[i]],
                                          exposure_iv = SNP_all,
                                          max_retries = max_retries )
    )
   # l_full[[i]][["id.outcome"]]<-l_full[[i]][["outcome"]]

  }

  cli::cli_process_done()

  cli::cli_process_start("对合并工具变量去除连锁不平衡")

  exposure_dat <- plyr::rbind.fill(l_inst)
  id_exposure <- unique(exposure_dat$id.exposure)
  temp <- exposure_dat
  temp$id.exposure <- 1
  temp <- temp[order(temp$pval.exposure, decreasing = FALSE),
  ]
  temp <- subset(temp, !duplicated(SNP))

  if(clump=="online"){

    message("在线去除连锁不平衡中......")
    temp <- retry(operation = clump_data_online,
                             args=list(dat=temp,clump_kb = kb , clump_r2 = r2, pop=pop ),
                             max_retries = max_retries)

  }

  if(clump=="local"){
    message("本地去除连锁不平衡中......")
    temp <-tryCatch( clump_data_local(temp, clump_kb = kb , clump_r2 = r2, pop=pop ,
                                                 bfile = bfile , plink_bin = plink_bin ) ,
                     error = function(e){NULL}  )      }

  if(is.null(temp)){ warning( paste0("clump后找不到SNP，建议提高筛选的P值")  )

    return(temp)

  }

  cli::cli_process_done()

  cli::cli_process_start("harmonise矫正方向并整理数据")


  exposure_dat <- subset(exposure_dat, SNP %in% temp$SNP)
  d1 <- lapply(l_full, function(x) {
    subset(x, SNP %in% exposure_dat$SNP)
  }) %>% dplyr::bind_rows()
  stopifnot(length(unique(d1$id)) == length(unique(id_exposure)))
  d1 <- subset(d1, mr_keep.outcome)
  d2 <- subset(d1, id.outcome != id_exposure[1])
  d1 <- convert_outcome_to_exposure(subset(d1, id.outcome ==
                                             id_exposure[1]))
  d <- harmonise_data(d1, d2, action = 2)
  tab <- table(d$SNP)
  keepsnps <- names(tab)[tab == length(id_exposure) - 1]
  d <- subset(d, SNP %in% keepsnps)
  dh1 <- subset(d, id.outcome == id.outcome[1], select = c(SNP,
                                                           exposure, id.exposure, effect_allele.exposure, other_allele.exposure,
                                                           eaf.exposure, beta.exposure, se.exposure, pval.exposure))
  dh2 <- subset(d, select = c(SNP, outcome, id.outcome, effect_allele.outcome,
                              other_allele.outcome, eaf.outcome, beta.outcome, se.outcome,
                              pval.outcome))
  names(dh2) <- gsub("outcome", "exposure", names(dh2))
  dh <- rbind(dh1, dh2)
  cli::cli_process_done()
  return(dh)
}
